package com.itheima.tliasmanager.aop.test;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

//1.创建切面类：@Component  / @Aspect
@Component
@Aspect
public class MyAspect1 {


    /**
     * 提取公共切入点表达式
     *  1.定义无返回值，无参数的方法
     *  2.添加@Pointcut注解，指定切入点表达式
     *  3.如果的是公共public方法，其他类可以使用公用此切入点表达式
     */
    @Pointcut("execution(public * com.itheima.tliasmanager.controller.DeptController.list())")
    public void yuBrother(){}


    /**
     * 环绕通知，可以实现其他通知的所有功能
     * 在环绕通知中，自行通过ProceedingJoinPoint对象，调用目标方法
     */
    @Around("yuBrother()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {

        Object result = null;
        try {
            System.out.println("环绕-前置通知：执行时间："+ LocalDateTime.now());

            result = pjp.proceed();//手动调用目标方法

            System.out.println("环绕-返回后置通知：执行时间："+ LocalDateTime.now());
        } catch (Throwable e) {
            System.out.println("环绕-异常后置通知：执行时间："+ LocalDateTime.now());
            throw new RuntimeException(e);
        } finally {
            System.out.println("环绕-后置通知：执行时间："+ LocalDateTime.now());
        }
        return  result;
    }

    //2.编写通知方法
    //目标方法执行前执行
    @Before("yuBrother()")
    public void before(){
        System.out.println("前置通知：执行时间："+ LocalDateTime.now());
    }

    //目标方法执行后执行
    @After("yuBrother()")
    public void after(){
        System.out.println("后置通知：执行时间："+ LocalDateTime.now());
    }

    //目标方法正常执行后执行
    @AfterReturning("yuBrother()")
    public void afterReturning(){
        System.out.println("返回后通知：执行时间："+ LocalDateTime.now());
    }

    //目标方法异常后执行
    @AfterThrowing("yuBrother()")
    public void afterThrowing(){
        System.out.println("异常后通知：执行时间："+ LocalDateTime.now());
    }

}
